﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;

namespace Gakita.Controller
{
    /* This Controller handles the game by recieving input from the view and updating the model */
    class GameController : IController, View.Menu.IModelObserver
    {
        private View.Menu.HighScoreModel _highscoreModel;
        private Model.Model _model                                  =       new Model.Model();
        private View.GameView _gameView;
        private View.Camera _camera                                 =       new View.Camera();
        private MasterController.Controllers _nextController        =       MasterController.Controllers.Menu;       
        private bool _changeController                              =       false;

        public GameController(GraphicsDeviceManager aGraphics, ContentManager aContentManager, SpriteBatch aSpriteBatch,                                                   View.Menu.HighScoreModel aHighScoreModel)
        {
            _gameView = new View.GameView(aGraphics, aContentManager, aSpriteBatch);
            _highscoreModel = aHighScoreModel;
        }

        public void Update(float aElapsedTime)
        {
            // After the player died, the game is paused for a few seconds. During that time, no input is allowed
            if (_model.isGamePausedAfterDeath() != true)
            {
                //Deal with Input
                if (_gameView.DidPlayerPressJump())
                {
                    _model.DoJump();
                }

                if (_gameView.DidPlayerPressLeft())
                {
                    _model.MoveLeft();
                }

                if (_gameView.DidPlayerPressRight())
                {
                    _model.MoveRight();
                }

                if (_gameView.DidPlayerPressMenu())
                {
                    SetNextController(MasterController.Controllers.Menu);
                    _changeController = true;
                }
            }

            _model.Update(aElapsedTime, new View.Menu.IModelObserver[2] { _highscoreModel, this }, _gameView);

            //If the game is over, the user is returned to the menu
            if (_model.IsTheGameStillRunning() == false && Model.Model._isSelectLevelMode == false)
            {
                SetNextController(MasterController.Controllers.Menu);
                _changeController = true;
            }

        }

        public void Draw(float aElapsedTime, GraphicsDevice aGraphics)
        {
            Model.Level level = _model.GetLevel();

            // During the second level, there is a section where the camera is no longered centered on the player
            if (level.GetCurrentLevel() == Model.Level.Levels.second && _model.GetPlayerPosition().X > 61)
            {
                _camera.BottomOn(new Vector2(_model.GetPlayerPosition().X, 9),
                                  new Vector2(aGraphics.Viewport.Width, aGraphics.Viewport.Height),
                                  new Vector2(Model.Level._levelWidth, Model.Level._levelHeight));
            }
            // Standard camera Settings
            else
            {
                _camera.CenterOn(_model.GetPlayerPosition(),
                                  new Vector2(aGraphics.Viewport.Width, aGraphics.Viewport.Height),
                                  new Vector2(Model.Level._levelWidth, Model.Level._levelHeight));
            }
            _camera.SetZoom(96);

            _gameView.DrawEverything(aGraphics, level, _camera, _model.GetPlayerPosition(), _model.GetPlayerLivesLeft(), aElapsedTime,                                            _model.GetPlayerSpeed(), _model.GetCurrentTime(), _model.isGamePausedAfterDeath());
        }

        /* This method checks if the controller needs to be changed */
        public bool DidUserChangeController()
        {
            bool ret = _changeController;
            _changeController = false;
            return ret;
        }

        public void SetNextController(MasterController.Controllers aController)
        {
            _nextController = aController;
        }

        public MasterController.Controllers ControllerToChangeTo()
        {
            return _nextController;
        }

        /* This method is called by the model through the observer interface when the level is over so that the infocontroller can                      display the "inbetween levels screen" */
        public void LevelIsOver(int aTime, Model.Level.Levels aLevel)
        {
            SetNextController(MasterController.Controllers.Info);
            _changeController = true;
        }
    }
}
